package com.hunttown.mes.manage.service;

import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.common.cache.Cache;
import com.hunttown.common.domain.Page;
import com.hunttown.mes.rpc.api.IotRegionRpcService;
import com.hunttown.mes.rpc.domain.IotRegionDTO;
import com.hunttown.mes.rpc.domain.TransportTableChineseEnglishDTO;
import com.hunttown.mes.rpc.domain.TransportTableChineseEnglishDetailDTO;
import com.hunttown.mes.rpc.domain.query.IotRegionDTOQuery;
import com.hunttown.mes.rpc.domain.query.TransportTableChineseEnglishDetailDTOQuery;
import com.hunttown.mes.common.utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;

import java.util.*;
import java.util.stream.Collectors;

/**
 * created by wangjunfu on 2020-10-05 16:33:41
 */
@Service
public class IotRegionManageService {

    private final static Logger logger = LoggerFactory.getLogger(IotRegionManageService.class);

    private final IotRegionRpcService rpcService;
    private final AnalysisManageManageService manageService;
    private final TransportTableChineseEnglishManageService englishService;
    private final TransportTableChineseEnglishDetailManageService englishDetailService;
    private final Cache jedisCache;

    @Autowired
    public IotRegionManageService(IotRegionRpcService rpcService, TransportTableChineseEnglishManageService englishService, TransportTableChineseEnglishDetailManageService englishDetailService, AnalysisManageManageService manageService, Cache jedisCache) {
        this.rpcService = rpcService;
        this.englishService = englishService;
        this.englishDetailService = englishDetailService;
        this.manageService = manageService;
        this.jedisCache = jedisCache;
    }

    // 新增
    public IotRegionDTO insert(IotRegionDTO objDTO) {
        return rpcService.insert(objDTO);
    }

    // 通过ID修改
    public Boolean updateInfoById(IotRegionDTO objDTO) {
        Boolean isNext = rpcService.updateInfoById(objDTO);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(objDTO.getId());
        }
        return isNext;
    }

    // 通过Query修改
    public Boolean updateInfoByQuery(IotRegionDTOQuery objDTOQuery) {
        Boolean isNext = rpcService.updateInfoByQuery(objDTOQuery);

        //单体刷新
        if (isNext && objDTOQuery.getW_id() != null) {
            refreshCacheById(objDTOQuery.getW_id());
        }

        //批量刷新缓存
        if (isNext && objDTOQuery.getIds() != null) {
            List<Integer> list = new ArrayList<>();
            try {
                list = (List<Integer>) objDTOQuery.getIds();
            } catch (Exception e) {
                e.printStackTrace();
            }
            refreshCacheByIdList(list);
        }
        return isNext;
    }

    // 通过ID删除
    public Boolean delete(Integer id) {
        Boolean isNext = rpcService.deleteById(id);
        if (isNext) {
            // 刷新缓存
            refreshCacheById(id);
        }
        return isNext;
    }

    // 批量删除
    public Boolean deleteForBatch(String clearIds) {

        //处理 “,5,6,7,” 为List
        List<Integer> idList = FormatUtils.commaToList_Integer(clearIds);

        if (idList.size() == 0) {
            return false;
        }

        IotRegionDTOQuery query = new IotRegionDTOQuery();
        query.setDeleteFlag(1);
        query.setIds(idList);

        Boolean isNext = rpcService.updateInfoByQuery(query);
        if (isNext) {
            // 刷新缓存
            refreshCacheByIdList(idList);
        }

        return isNext;
    }

    // 通过ID获取
    public IotRegionDTO getById(Integer id) {
        if (id <= 0) {
            return null;
        }
        return rpcService.selectById(id);
    }

    // 通过Query获取
    public IotRegionDTO getByQuery(IotRegionDTOQuery objDTOQuery) {
        return rpcService.selectObjByQuery(objDTOQuery);
    }

    // 获取分页列表
    public Page<IotRegionDTO> getForPage(IotRegionDTOQuery objDTOQuery) {
        return rpcService.getListForPage(objDTOQuery);
    }

    // 改变某条记录的使用状态
    public Boolean changeState(Integer id, Integer state) {
        IotRegionDTO obj = new IotRegionDTO();
        obj.setStopFlag(state);
        obj.setId(id);
        return updateInfoById(obj);
    }

    /**
     * 先从缓存中获取数据
     * 如果缓存为空，从数据库中获取，并将获取的数据添加到缓存。
     *
     * @param id id
     * @return obj
     */
    public IotRegionDTO getFromCacheId(Integer id) {
        if (id == null || id <= 0) {
            return null;
        }

        IotRegionDTO obj = jedisCache.oget(KeyConstants.IOT_REGION_INFO_KEY_ID + id, IotRegionDTO.class);
        if (obj == null) {
            obj = getById(id);
            if (obj != null) {
                jedisCache.oset(KeyConstants.IOT_REGION_INFO_KEY_ID + id, obj);
            }
        }

        return obj;
    }

    //region 刷新缓存

    /**
     * 刷新缓存
     *
     * @param id id
     */
    private void refreshCacheById(Integer id) {
        if (id == null || id <= 0) {
            return;
        }

        IotRegionDTO obj = getById(id);
        if (obj != null) {
            jedisCache.delete(KeyConstants.IOT_REGION_INFO_KEY_ID + id);
        }
    }

    /**
     * 刷新缓存(批量)
     *
     * @param idList list
     */
    private void refreshCacheByIdList(List<Integer> idList) {
        if (idList == null || idList.size() == 0) {
            return;
        }

        for (Integer id : idList) {
            refreshCacheById(id);
        }
    }
    //endregion

    //region 数据查看

    /**
     * 组装实体信息为前台可展示的格式
     * 可做定制化的配置
     * 存放位置：各业务的Service中
     *
     * @param model     Sevelet Model
     * @param tableName 数据库表名
     * @param obj       对象
     * @return model
     */
    public Model assembleObjInfo(Model model, String tableName, IotRegionDTO obj) {

        // 结果集返回一个map
        LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

        // 显示标题
        String showTitle = "详情";

        // 获取数据库中英文对照表主表信息
        TransportTableChineseEnglishDTO englishDTO = englishService.getByTableName(tableName);

        if (obj == null || englishDTO == null) {
            map.put("没有查询到数据！", "");
        } else {
            Map<String, Object> origin_map = GeneralUtils.ergodicModel(FastJsonUtils.toJSONString(obj), IotRegionDTO.class);

            if (origin_map != null) {
                // 根据表ID（tableId）获取表字段信息
                TransportTableChineseEnglishDetailDTOQuery query = new TransportTableChineseEnglishDetailDTOQuery();
                query.setTableId(englishDTO.getId());
                query.setDeleteFlag(0);
                query.setPageSize(1000);
                Page<TransportTableChineseEnglishDetailDTO> detailPage = englishDetailService.getForPage(query);

                if (detailPage != null && detailPage.getItems().size() > 0) {
                    Object value;
                    String newfield;
                    for (TransportTableChineseEnglishDetailDTO item : detailPage.getItems()) {
                        if (item.getFrontShow() == 1) {
                            newfield = GeneralUtils.standardFields(item.getFieldName());
                            value = origin_map.get(newfield);
                            if (item.getFieldType().toUpperCase().equals("TIMESTAMP")) {
                                map.put(item.getFieldNameCn(), DateConvertUtils.cstToShortStrDate(value.toString()));
                            } else {

                                if (value == null || StringUtils.isBlank(value.toString())) {
                                    map.put(item.getFieldNameCn(), "--");
                                    continue;
                                }

                                //region 开始个性化设置
                                if (newfield.equals("adminId")) { //创建人
                                    value = manageService.getNickNameFromCache(Integer.valueOf(value.toString()));
                                }
                                if (newfield.equals("stopFlag")) { //启停用状态
                                    value = value.equals(0) ? "启用" : "停用";
                                }
                                //endregion

                                map.put(item.getFieldNameCn(), value.toString());
                            }
                        }
                    }
                }
            }
        }

        model.addAttribute("showTitle", showTitle);
        model.addAttribute("showResult", map);

        return model;
    }

    //endregion

    //region 获取左树

    /**
     * 构建左侧分类树 A2-1
     * 适用于：抄表模块，区域下挂电表设备
     *
     * @return list
     */
    public List<String> createBasicTree() {
        IotRegionDTOQuery regionQuery = new IotRegionDTOQuery();
        regionQuery.setStopFlag(0);
        regionQuery.setPageSize(1000);
        List<IotRegionDTO> list = rpcService.getListForPage(regionQuery).getItems();

        return getList(list, 0, 0);
    }

    /**
     * 递归 A2-2
     *
     * @param mainList 区域列表
     * @param parentId 父ID
     * @param deep     菜单深度
     * @return list
     */
    private List<String> getList(List<IotRegionDTO> mainList, Integer parentId, Integer deep) {

        List<String> result = new ArrayList<>();

        if (mainList == null || mainList.size() == 0) {
            return result;
        }

        deep += 1;

        List<IotRegionDTO> filterList = mainList.stream().filter(s -> s.getParentId().equals(parentId)).collect(Collectors.toList());

        if (filterList.size() == 0) {
            return result;
        }

        result.add("<ul>");
        for (IotRegionDTO item : filterList) {

            //由于数据表设计，不同深度的菜单获取不同的显示名称
            String showname = item.getArea();
            if (deep == 2) {
                showname = item.getBuilding();
            }
            if (deep == 3) {
                showname = item.getUnit();
            }

            result.add("<li data-jstree='{\"opened\": \"true\", \"icon\":\"md-home\"}'><a href='javascript:void(0);' onclick='getElectricAreaReport(" + item.getId() + ")'>" + showname + "</a>");

            //region 【方案一】同时取出区域下面的房间（逻辑有更改，但是还可以使用）（已弃用）

            //01.获取房间号/商户号（会员表中，前台必填）
            //TransportUserDTOQuery userQuery = new TransportUserDTOQuery();
            //userQuery.setIotRegionId(item.getId());
            //Page<TransportUserDTO> userPage = userService.getForPage(userQuery);

            //02.获取此房间的所属用户
            //result.add("<ul>");
            //for (TransportUserDTO dto : userPage.getItems()) {
            //    result.add("<li data-jstree='{\"icon\":\"md-room\"}'><a href='javascript:void(0);' onclick='getElectricRoomReport(" + dto.getId() + ")'>" + dto.getDetailAddress() + "</a></li>");
            //}
            //result.add("</ul>");

            //endregion

            //递归
            List<String> list = getList(mainList, item.getId(), deep);
            for (String child : list) {
                result.add(child);
            }

            result.add("</li>");
        }
        result.add("</ul>");

        return result;
    }
    //endregion

    //region 取出记录的子集

    //取出每条记录的子类，一并返回
    public List<IotRegionDTO> getChildrenForEach(List<IotRegionDTO> list, String mark) {
        if (list == null || list.size() == 0) {
            return list;
        }

        List<IotRegionDTO> return_list = new ArrayList<>();
        List<IotRegionDTO> child_list = new ArrayList<>();

        for (IotRegionDTO item : list) {
            item.setShowName(item.getArea());
            child_list = getChildrenById(item, mark, 1);
            return_list.addAll(child_list);
        }

        return return_list;
    }

    //取出每条记录的子类，一并返回（具体实施）
    private List<IotRegionDTO> getChildrenById(IotRegionDTO dto, String mark, Integer deep) {
        List<IotRegionDTO> child_list = new ArrayList<>();
        child_list.add(dto);

        if (mark.equals("|")) {
            mark += "┄";
        } else {
            mark += " ┄┄";
        }

        deep++;

        IotRegionDTOQuery query = new IotRegionDTOQuery();
        query.setParentId(dto.getId());
        query.setStopFlag(0);
        query.setPageSize(1000);
        Page<IotRegionDTO> dataPage = getForPage(query);

        if (dataPage != null && dataPage.getItems().size() > 0) {
            for (IotRegionDTO item : dataPage.getItems()) {
                String showname = item.getArea();
                if (deep == 2) {
                    showname = item.getBuilding();
                }
                if (deep == 3) {
                    showname = item.getUnit();
                }

                item.setShowName(mark + " " + showname);
                List<IotRegionDTO> next_list = getChildrenById(item, mark, deep);
                child_list.addAll(next_list);
            }
        }

        return child_list;
    }

    //endregion

    //region 更新记录的子类的信息

    /**
     * 更新记录的子类的信息
     *
     * @param id   父ID
     * @param name 要更新的名称
     * @param deep 深度：1小区 2楼宇 3单元
     */
    public void updateChildInfo(Integer id, String name, Integer deep) {
        IotRegionDTOQuery query = new IotRegionDTOQuery();
        query.setParentId(id);
        query.setStopFlag(0);
        query.setPageSize(1000);
        Page<IotRegionDTO> dataPage = getForPage(query);

        for (IotRegionDTO item : dataPage.getItems()) {
            IotRegionDTO update = new IotRegionDTO();
            update.setId(item.getId());
            if (deep == 1) {
                update.setArea(name);
                updateInfoById(update);
            }
            if (deep == 2) {
                update.setBuilding(name);
                updateInfoById(update);
            }

            updateChildInfo(item.getId(), name, deep);
        }
    }
    //endregion

    /**
     * 通过递归获取当前id 数据及他所有子分类id
     * 返回 List id
     *
     * @param id ID
     * @return list
     */
    public List<Integer> getChildIdsByRecursion(Integer id) {
        List<Integer> idList = new ArrayList<>();
        if (id == null || id <= 0) {
            return idList;
        }
        idList.add(id);

        IotRegionDTOQuery query = new IotRegionDTOQuery();
        query.setParentId(id);
        query.setStopFlag(0);
        query.setPageSize(1000);

        Page<IotRegionDTO> childList = getForPage(query);
        if (childList != null && childList.getItems().size() > 0) {
            for (IotRegionDTO item : childList.getItems()) {
                List<Integer> next_list = getChildIdsByRecursion(item.getId());
                idList.addAll(next_list);
            }
        }

        return idList;
    }

}